package com.smart.service.impl;

import com.smart.global.GlobalWord;
import com.smart.pojo.*;
import com.smart.req.LeaveCompleteData;
import com.smart.req.ReimbursementCompleteData;
import com.smart.service.*;
import org.activiti.engine.HistoryService;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.impl.identity.Authentication;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;

@Service
public class ReimbursementProcessServiceImpl implements ReimbursementProcessService {
    @Autowired
    RepositoryService repositoryService;

    @Autowired
    RuntimeService runtimeService;

    @Autowired
    TaskService taskService;

    @Autowired
    HistoryService historyService;

    @Autowired
    IReimbursementBillService reimbursementBillService;

    @Autowired
    IRoleService roleService;

    @Autowired
    IUserService userService;

    @Autowired
    IDepartmentService departmentService;
    @Autowired
    ISalaryService salaryService;


    @Override
    @Transactional
    public boolean startReimbursementProcess(ReimbursementBill reimbursementBill) {
        //先保存报销单,初始状态为0审批中
        reimbursementBill.setStatus(0);
        boolean save = reimbursementBillService.save(reimbursementBill);

        //流程推进变量
        Map<String, Object> map = new HashMap<>();
        //设定申请人
        map.put("empId", reimbursementBill.getUserId());
        //设定财务部长
        User personnelMinister = userService.lambdaQuery()
                .eq(User::getRoleId, GlobalWord.FINANCE_MINISTER_ROLE_ID)
                .one();
        map.put("financeMinisterId", personnelMinister.getId());
        //设定总经理
        User manger = userService.lambdaQuery()
                .eq(User::getRoleId, GlobalWord.MANGER_ROLE_ID)
                .one();
        map.put("mangerId", manger.getId());
        //设定报销金额
        map.put("amount", reimbursementBill.getAmount());

        //判断是什么角色报销，设定申请级别
        User reimbursementUser = userService.getById(reimbursementBill.getUserId());
        if (reimbursementUser.getRoleId() != null) {
            //获取角色信息
            Role LeaveRole = roleService.getById(reimbursementUser.getRoleId());
            //判断是否经理角色
            if (LeaveRole.getId().equals(GlobalWord.MANGER_ROLE_ID)) {
                //三级审批
                map.put("level", GlobalWord.LEVEL3);
            } else if (LeaveRole.getIsDepartmentRole() == 0) {    //不是部门角色
                //二级审批
                map.put("level", GlobalWord.LEVEL2);
            } else if (LeaveRole.getIsLeader() == 1) {          //是部长角色
                //二级审批
                map.put("level", GlobalWord.LEVEL2);
            } else {               //部门普通员工角色
                //一级审批
                map.put("level", GlobalWord.LEVEL1);
                //查询申请用户的所属部门
                Department department = departmentService.queryByUserId(reimbursementBill.getUserId());
                map.put("ministerId", department.getLeader());
            }
        } else {
            //二级审批
            map.put("level", GlobalWord.LEVEL2);
        }

        //构造流程实例关联报销单的唯一标识
        String businessKey = GlobalWord.REIMBURSEMENT_KEY + "." + reimbursementBill.getId();
        //开启请假流程
        ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(GlobalWord.REIMBURSEMENT_KEY, businessKey, map);
        return save & !ObjectUtils.isEmpty(processInstance);
    }

    @Override
    @Transactional
    public void complete(ReimbursementCompleteData reimbursementCompleteData) {
        //设置流程推进信息
        Map<String, Object> map = new HashMap<>();
        map.put("msg", reimbursementCompleteData.getSequence());

        //判断是否要更新报销单信息
        if (reimbursementCompleteData.getReimbursementBill() != null) {
            reimbursementCompleteData.getReimbursementBill().setStatus(0);
            reimbursementBillService.updateById(reimbursementCompleteData.getReimbursementBill());
            map.put("amount", reimbursementCompleteData.getReimbursementBill().getAmount());
        }

        //获取当前任务节点
        Task task = taskService.createTaskQuery().taskId(reimbursementCompleteData.getTaskId()).singleResult();
        //获取businessKey
        ProcessInstance pi = runtimeService.createProcessInstanceQuery()
                .processInstanceId(task.getProcessInstanceId())
                .singleResult();
        String businessKey = pi.getBusinessKey();

        //获取当前流程实例关联的请假单
        ReimbursementBill bill = reimbursementBillService.getById(Long.parseLong(businessKey.split("\\.")[1]));

        //设置批注人以及批注信息
        Authentication.setAuthenticatedUserId(reimbursementCompleteData.getUserId().toString());
        taskService.addComment(task.getId(), task.getProcessInstanceId(), reimbursementCompleteData.getComment());

        //如果是驳回流程,更新请假单信息
        if (reimbursementCompleteData.getSequence().equals("驳回")) {
            bill.setStatus(2);
            reimbursementBillService.updateById(bill);
        }

        //推进流程
        taskService.complete(reimbursementCompleteData.getTaskId(), map);

        //判断流程是否结束
        ProcessInstance processInstance = runtimeService.createProcessInstanceQuery()
                .processInstanceId(task.getProcessInstanceId())
                .singleResult();

        if (processInstance == null) {
            //流程结束，处理报销成功相关信息
            bill.setStatus(1);
            reimbursementBillService.updateById(bill);

            //计算报销金额
            Salary salary = salaryService.getByUserId(bill.getUserId());
            salary.setReimbursementAmount(salary.getReimbursementAmount().add(bill.getAmount()));
            salaryService.updateById(salary);
        }
    }
}
